/*
 * @Description: ol 2D 地图入口文件
 * @Date: 2022-01-04 15:27:38
 * @Author: yeming
 */

/* eslint-disable space-before-function-paren */
/* eslint-disable new-cap */
/* eslint-disable array-bracket-spacing */

import 'ol/ol.css' // 引入所需的css，这项是必须的。
import OlMousePosition from 'ol/control/MousePosition';
import OlScaleLine from 'ol/control/ScaleLine';
import { createStringXY } from 'ol/coordinate';
import { transform } from 'ol/proj' // transform(坐标、源、目标) 【将坐标从源投影转换为目标投影。这将返回一个新坐标（并且不会修改原始坐标）】
import { fromLonLat, toLonLat } from 'ol/proj.js'
// 引入 Map 和 View。这项也是必须的。
// Map是一个地图容器，是最最最核心的部分。Map可以加载各类地图与功能控件，也用于渲染、表现动态地图。每一个地图都是一个Map对象。
// View是地图视图，控制地图缩放等基础交互，以及地图投影坐标系、地图中心、分辨率、旋转角度等。
import { Map, View } from 'ol'
import OlDragPan from 'ol/interaction/DragPan'

const DEFAULT_MAP_CENTER_LATLNG = [116, 40, 80]

const scaleLine = new OlScaleLine({ target: document.getElementById('scaleLine') })

// 鼠标移动显示经纬度坐标位置
const mousePosition = new OlMousePosition({
  coordinateFormat: createStringXY(4),
  projection: 'EPSG:4326',
  className: 'mouse-position',
  undefinedHTML: "鼠标位置（经纬度）"
})

class Ol2d {
  constructor(options = {}, layers = [], mapType = 1) {
    const that = this
    this.map2d = new Map({
      layers: layers,
      // controls: [scaleLine, mousePosition],
      controls: [scaleLine],
      target: options.target,
      view: new View({
        center: transform(DEFAULT_MAP_CENTER_LATLNG, 'EPSG:4326', 'EPSG:3857'),
        constrainResolution: false,
        zoom: options.zoom || 5,
        minZoom: 1,
        maxZoom: 19,
        enableRotation: false
      })
      // maxTilesLoading: 16,// 同时加载的最大瓷砖数 默认16
      // loadTilesWhileAnimating: false, // 默认false；当设置为true，块层将会在动画中加载。会提升用户体验，但是会在低内存的设备上出现动画卡顿。
      // loadTilesWhileInteracting: false, // 默认false；当设置为true，块层会在地图交互时加载。会提升用户体验，但是会在低内存的设备上使地图平移和缩放出现不稳定。
      // moveTolerance: 1, // 光标必须移动的最小距离(以像素为单位)才能被检测为map move事件，而不是单击。增加这个值可以使单击地图变得更容易
      // pixelRatio: window.devicePixelRatio, // 设备分辨率
      // keyboardEventTarget: ''// 要监听键盘事件的元素
    })
    this.mapType = mapType
    this.pan = this.getPan()
    this.selectedFeature = null
    this.view = this.map2d.getView()
  }
  zoomIn () {
    let zoom = this.view.getZoom() + 1
    this.view.setZoom(zoom)
  }
  zoomOut () {
    let zoom = this.view.getZoom() - 1
    this.view.setZoom(zoom)
  }
  setZoom (zoom) {
    this.view.setZoom(zoom)
  }
  getZoom () {
    return Math.floor(this.view.getZoom())
  }
  locationToSomeWhereByLatlng (latlng, zoom) {
    this.view.setCenter(transform(latlng, 'EPSG:4326', 'EPSG:3857'))
    this.view.setZoom(zoom)
  }
  /**
   * @desc: 设置地图模式 0-只读 1-开放 2-绘图
   * @desc: 缩放事件的核心思想就是：MinZoom和MaxZoom设为一个值
   * @desc: 滚动事件就是禁止任何element drag
   * @param {Number} type
   * @return {*}
   * @use: 使用示例
   */
  setMapPanAndZoom (type) {
    if (type <= 0) {
      let zoom = this.getZoom()
      this.view.setMinZoom(zoom)
      this.view.setMaxZoom(zoom)
      this.pan.setActive(false) // false 当前地图不可拖动
    } else {
      this.view.setMinZoom(1)
      this.view.setMaxZoom(19)
      this.pan.setActive(true) // false 当前地图可拖动
    }
  }
  getPan () {
    let pan = null
    this.map2d.getInteractions().forEach((element, index, array) => {
      if (element instanceof OlDragPan) pan = element
    })
    return pan
  }
}

export default Ol2d


